package com.chj.utils;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

public final class JsonUtil {
    private static final Logger logger = LoggerFactory.getLogger(JsonUtil.class);
    private static final ObjectMapper objectMapper = new ObjectMapper();

    public static <T> String toJson(T data) {
        try {
            return objectMapper.writeValueAsString(data);
        } catch (JsonProcessingException e) {
            logger.error("error happened in JsonUtils.toJson.", e);
        }
        return "";
    }

    public static String getJson(Object data) {
        try {
            return objectMapper.writeValueAsString(data);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static <T> T getObject(InputStream data, Class<T> clazz) {
        try {
            return objectMapper.readValue(data, clazz);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static <T> T toObject(String json, Class<T> clazz) throws Exception {
        try {
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            return objectMapper.readValue(json, clazz);
        } catch (Exception e) {
            logger.error("error happened in JsonUtils.toObject.", e);
            throw new Exception(e);
        }
    }

    public static <T> T toObject(Object singleObject, Class<T> clazz) throws Exception {
        try {
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            byte[] json = objectMapper.writeValueAsBytes(singleObject);
            logger.info(new String(json));
            T pojo = objectMapper.readValue(json, clazz);
            return pojo;
        } catch (Exception e) {
            logger.error("error happened in JsonUtils.toObject.", e);
            throw new Exception(e);
        }
    }
    
	public static <T> List<T> getList(String jsonStr, Class<T> cls) {
		try {
			if (StringUtils.isEmpty(jsonStr)) {
				return null;
			}
			// 专门创建bean的集合类类型供json转换
			JavaType javaType = getCollectionType(objectMapper, ArrayList.class, cls);
			return objectMapper.readValue(jsonStr, javaType);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static <K, V> Map<K, V> getMap(String jsonStr, Class<K> keycls, Class<V> valuecls) {
		try {
			if (StringUtils.isEmpty(jsonStr)) {
				return null;
			}
			// 专门创建bean的集合类类型供json转换
			JavaType javaType = getCollectionType(objectMapper, Map.class, keycls, valuecls);
			return objectMapper.readValue(jsonStr, javaType);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
    
    
	public static JavaType getCollectionType(ObjectMapper objectMapper, Class<?> collectionClass, Class<?>... elementClasses) {
		return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
	}
}
